//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.Blackboard.Wcf
{
    using System;
    using System.ServiceModel;
    using Microsoft.Research.eResearch.Blackboard.Common;
    using Microsoft.Research.eResearch.Blackboard.Interfaces;
    using Microsoft.Research.eResearch.Common.Eventing;

    /// <summary>
    /// Hosts a <see cref="WcfPublisherMessageService"/>.
    /// </summary>
    public class WcfPublisherMessageServiceHost : IPublisherMessageReceiver
    {
        /// <summary>
        /// Instance of WCF service host.
        /// </summary>
        private ServiceHost serviceHost;

        /// <summary>
        /// Initializes a new instance of the <see cref="WcfPublisherMessageServiceHost"/> class.
        /// </summary>
        public WcfPublisherMessageServiceHost()
        {
        }

        /// <summary>
        /// Occurs when a new publisher registers with the Blackboard.
        /// </summary>
        public event EventHandler<PublisherRegisteringEventArgs> PublisherRegistering;

        /// <summary>
        /// Occurs when a previously-registered publisher unregisters with the Blackboard.
        /// </summary>
        public event EventHandler<PublisherUnregisteringEventArgs> PublisherUnregistering;

        /// <summary>
        /// Occurs when a new BlackboardMessage is received from a publisher.
        /// </summary>
        public event EventHandler<BlackboardMessageReceivedEventArgs> BlackboardMessageReceived;

        /// <summary>
        /// Starts the underlying WcfPublisherMessageService so that the blackboard can listen for messages from
        /// publishers.
        /// </summary>
        public void Start()
        {
            Stop();

            serviceHost = new ServiceHost(typeof(WcfPublisherMessageService));

            serviceHost.Extensions.Add(
                new PublisherMessageReceiverExtension(
                    OnPublisherRegistering,
                    OnPublisherUnregistering,
                    OnBlackboardMessageReceived));

            serviceHost.Open();
        } 

        /// <summary>
        /// Stops the underlying WcfPublisherMessageService so that the blackboard stops listening for messages
        /// from publisher.
        /// </summary>
        public void Stop()
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
                serviceHost = null;
            }
        } 

        /// <summary>
        /// Raises the PublisherRegistering event.
        /// </summary>
        /// <param name="returnAddress">The return address.</param>
        /// <returns>The agregated subscription profile.</returns>
        protected virtual SubscriptionProfile OnPublisherRegistering(Uri returnAddress)
        {
            PublisherRegisteringEventArgs args = new PublisherRegisteringEventArgs(returnAddress);
            this.PublisherRegistering.Fire(this, args);
            return args.OutgoingSubscriptionProfile;
        } 

        /// <summary>
        /// Raises the PublisherUnregistering event.
        /// </summary>
        /// <param name="returnAddress">The return address.</param>
        protected virtual void OnPublisherUnregistering(Uri returnAddress)
        {
            this.PublisherUnregistering.Fire(this, new PublisherUnregisteringEventArgs(returnAddress));
        } 

        /// <summary>
        /// Raises the BlackboardMessageReceived event.
        /// </summary>
        /// <param name="message">The message.</param>
        protected virtual void OnBlackboardMessageReceived(BlackboardMessage message)
        {
            this.BlackboardMessageReceived.Fire(this, new BlackboardMessageReceivedEventArgs(message));
        } 
    }
}
